package yxy.game.pm2.module.plainsCraft;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.joda.time.DateTime;
import org.redisson.api.RList;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.game.pm2.bean.db.newDao.PlainsCraftRecordDAO;
import yxy.game.pm2.bean.db.po.PlainsCraftRecordPo;
import yxy.game.pm2.bean.module.PlayerModule;

import java.util.ArrayList;
import java.util.List;

public class PlainsCraftRecord extends PlayerModule {
	// bean===========================================================================
	private String code;//
	private DateTime date;// 时间
	private ArrayList<String> recordCodes = new ArrayList<>();// 录像码
	private boolean isWin;// 攻方是否胜利

	private PlainsCraftRecordPlayerInfo infoA;// 进攻方
	private PlainsCraftRecordPlayerInfo infoB;// 防守方



	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public DateTime getDate() {
		return date;
	}

	public void setDate(DateTime date) {
		this.date = date;
	}

	public ArrayList<String> getRecordCodes() {
		return recordCodes;
	}

	public void setRecordCodes(ArrayList<String> recordCodes) {
		this.recordCodes = recordCodes;
	}

	public boolean isWin() {
		return isWin;
	}

	public void setWin(boolean isWin) {
		this.isWin = isWin;
	}

	public PlainsCraftRecordPlayerInfo getInfoA() {
		return infoA;
	}

	public void setInfoA(PlainsCraftRecordPlayerInfo infoA) {
		this.infoA = infoA;
	}

	public PlainsCraftRecordPlayerInfo getInfoB() {
		return infoB;
	}

	public void setInfoB(PlainsCraftRecordPlayerInfo infoB) {
		this.infoB = infoB;
	}
	// func===========================================================================
	// redis==========================================================================

	static public String key(String playerCode) {
		return String.format("PLAYER:%s:MODULE:PLAINSCRAFTRECORD", playerCode);
	}

	static private RList<PlainsCraftRecord> touch(String playerCode) throws RedisException {
		return RedisManager.client(redis()).getList(key(playerCode));
	}

	static public List<PlainsCraftRecord> get(String playerCode) {
		try {
			List<PlainsCraftRecord> list = touch(playerCode).readAll();
			//缓存没数据从数据库读取并放到redis
			if (list.size() <= 0) {
				List<PlainsCraftRecordPo> poList = PlainsCraftRecordDAO.getList(playerCode);
				for(int i =0 ;i <poList.size();i++){
					PlainsCraftRecord PlainsCraftRecord = toBean(poList.get(i),playerCode);
					list.add(PlainsCraftRecord);
				}

				if (list.size() > 0) {
					//将数据放到缓存
					touch(playerCode).addAll(list);
				}

			}
			return list;
		} catch (RedisException e) {
			e.printStackTrace();
			return new ArrayList<>();
		}
	}



	static public void add(String playerCode, PlainsCraftRecord record) {
		try {
			RList<PlainsCraftRecord> rlist = touch(playerCode);
			rlist.add(0, record);
			if (rlist.size() > 20) {
				rlist.trim(0, 19);
			}
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}



	//存储到数据库的方法
	public static void saveToDB(String playerCode) {
		try {
			System.out.println("PlainsCraftRecord执行saveToDB");
			RList<PlainsCraftRecord> rList = touch(playerCode);
			if (rList.isExists()) {
				long updateTime = System.currentTimeMillis();
				//存储
				List<PlainsCraftRecordPo> PlainsCraftRecordPoList = new ArrayList<>();
				List<PlainsCraftRecord> PlainsCraftRecordList = rList.readAll();
				for (PlainsCraftRecord record : PlainsCraftRecordList) {
					PlainsCraftRecordPo po = toDbBean(record, playerCode, updateTime);
					PlainsCraftRecordPoList.add(po);
				}
				//保存数据库
				PlainsCraftRecordDAO.replace(PlainsCraftRecordPoList);
				//
				PlainsCraftRecordDAO.delete(playerCode, updateTime);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//将bean转成po
	private static PlainsCraftRecordPo toDbBean(PlainsCraftRecord record, String playerCode, long updateTime) {
		PlainsCraftRecordPo po = new PlainsCraftRecordPo();
		po.setPlayerCode(playerCode);
		po.setCode(record.getCode());
		po.setDate(record.getDate().toDate());
		JSONArray jsonArray = (JSONArray)JSONArray.toJSON(record.getRecordCodes());
		po.setRecordCodes(jsonArray.toString());
		po.setWin(record.isWin());
		JSONObject infoA = (JSONObject)JSONObject.toJSON(record.getInfoA());
		JSONObject infoB = (JSONObject)JSONObject.toJSON(record.getInfoB());
		po.setInfoA(infoA.toString());
		po.setInfoB(infoB.toString());
		po.setUpdateTime(updateTime);
		return po;
	}


	//将db转回bean
	private static PlainsCraftRecord toBean(PlainsCraftRecordPo po, String playerCode) {
		PlainsCraftRecord PlainsCraftRecord = new PlainsCraftRecord();
		PlainsCraftRecord.setPlayerCode(playerCode);
		PlainsCraftRecord.setPlayerCode(po.getPlayerCode());
		PlainsCraftRecord.setCode(po.getCode());
		PlainsCraftRecord.setDate(new DateTime(po.getDate()));

		ArrayList<String> recordCodes = JSON.parseObject(po.getRecordCodes(), new TypeReference<ArrayList<String>>() {
		});
		PlainsCraftRecord.setRecordCodes(recordCodes);

		PlainsCraftRecord.setWin(po.isWin());

		PlainsCraftRecordPlayerInfo infoA = JSON.parseObject(po.getInfoA(), new TypeReference<PlainsCraftRecordPlayerInfo>() {
		});
		PlainsCraftRecord.setInfoA(infoA);

		PlainsCraftRecordPlayerInfo infoB = JSON.parseObject(po.getInfoB(), new TypeReference<PlainsCraftRecordPlayerInfo>() {
		});
		PlainsCraftRecord.setInfoB(infoB);
		return PlainsCraftRecord;
	}

	//移除缓存数据
	public static void removeAllFromRedis(String playerCode) {
		try {
			touchBucket(key(playerCode)).delete();
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}

	// lock==========================================================================

	@Override
	public String lockKey() {
		return String.format("lock:%s", key(getPlayerCode()));
	}

	/** 录像用玩家信息快照 */
	static public class PlainsCraftRecordPlayerInfo {
		private String playerCode;
		private long power;
		private int level;
		private int rank;

		public String getPlayerCode() {
			return playerCode;
		}

		public void setPlayerCode(String playerCode) {
			this.playerCode = playerCode;
		}

		public long getPower() {
			return power;
		}

		public void setPower(long power) {
			this.power = power;
		}

		public int getLevel() {
			return level;
		}

		public void setLevel(int level) {
			this.level = level;
		}

		public int getRank() {
			return rank;
		}

		public void setRank(int rank) {
			this.rank = rank;
		}
	}

	@Override
	public String toString() {
		return "PlainsCraftRecord{" +
				"code='" + code + '\'' +
				", date=" + date +
				", recordCodes=" + recordCodes +
				", isWin=" + isWin +
				", infoA=" + infoA +
				", infoB=" + infoB +
				'}';
	}
}
